﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using BoxSharp;

namespace BoxSharpNote
{
    public class BoxSharpNote : AddonInstance
    {
        private AddonInterface myInterface = null;
        private ToolTip tip = null;

        public override void AddonMain(AddonInterface addonInterface)
        {
            myInterface = addonInterface;

            myInterface.AddonInitializing += new AddonEventHandler(myInterface_AddonInitializing);
            myInterface.AddonFinalizing += new AddonEventHandler(myInterface_AddonFinalizing);
        }

        void myInterface_AddonFinalizing()
        {
        }

        void myInterface_AddonInitializing()
        {
            NotesManager.SetPath(myInterface.Path);
            NotesManager.Refresh();

            tip = new ToolTip();
            tip.Content = "/note\r\nOpen BoxSharp Note window to show existing notes.\r\n\r\n/note text\r\nAdd a note with the content \"text\".";
            tip.HasDropShadow = true;
            tip.PlacementTarget = myInterface.Box;
            tip.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
            tip.IsOpen = false;
            tip.Padding = new Thickness(5);
            tip.VerticalOffset = 5;

            myInterface.OnCommand += new CommandEventHandler(myInterface_OnCommand);
            myInterface.Box.TextChanged += new TextChangedEventHandler(Box_TextChanged);
        }

        void Box_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (myInterface.Box.Text == "/note" || myInterface.Box.Text.StartsWith("/note "))
            {
                tip.IsOpen = true;
            }
            else
            {
                tip.IsOpen = false;
            }
        }

        void myInterface_OnCommand(string bscommand)
        {
            if (bscommand.ToLower().StartsWith("/note ") && bscommand.Length > 6)
            {
                string noteContent = bscommand.Substring(6);
                Note newNote = new Note();
                newNote.Time = DateTime.Now;
                newNote.Content = noteContent;

                NotesManager.AddNote(newNote);
                myInterface.Box.Text = "";

                if (NotesManager.Presenter == null)
                {
                    NotePresenter presenter = new NotePresenter();
                    presenter.Left = myInterface.MainWindow.Left;
                    presenter.Top = myInterface.MainWindow.Top + myInterface.MainWindow.ActualHeight + 10;
                    presenter.Show();
                }
            }
            else if (bscommand == "/note")
            {
                if (NotesManager.Presenter != null)
                {
                    NotesManager.Presenter.Show();
                }
                else
                {
                    NotePresenter presenter = new NotePresenter();
                    presenter.Left = myInterface.MainWindow.Left;
                    presenter.Top = myInterface.MainWindow.Top + myInterface.MainWindow.ActualHeight + 10;
                    presenter.Show();
                }

                myInterface.Box.Text = "";
            }
        }
    }

    public class NotePresenter : Window
    {
        private ListBox listNotes = new ListBox();

        public void RefreshNotes()
        {
            listNotes.Items.Clear();

            foreach (Note note in NotesManager.Notes)
            {
                StackPanel panelNote = new StackPanel();
                panelNote.Orientation = Orientation.Horizontal;

                NoteItem newItem = new NoteItem();
                newItem.Note = note;
                newItem.Panel = panelNote;

                TextBlock textTime = new TextBlock();
                textTime.VerticalAlignment = VerticalAlignment.Top;
                textTime.Text = note.Time.ToString();
                textTime.Margin = new Thickness(0, 5, 10, 5);

                TextBlock textContent = new TextBlock();
                textContent.VerticalAlignment = VerticalAlignment.Center;
                textContent.Width = 300;
                textContent.TextWrapping = TextWrapping.Wrap;
                textContent.Margin = new Thickness(10, 5, 10, 5);
                textContent.Text = note.Content;
                if (textContent.Text.EndsWith("\r\n"))
                {
                    textContent.Text = textContent.Text.Substring(0, textContent.Text.Length - 2);
                }

                Button buttonDelete = new Button();
                buttonDelete.Content = "Delete";
                buttonDelete.Tag = newItem;
                buttonDelete.Height = 22;
                buttonDelete.Click += new RoutedEventHandler(buttonDelete_Click);
                buttonDelete.VerticalAlignment = VerticalAlignment.Top;
                buttonDelete.Margin = new Thickness(0, 2, 5, 2);

                panelNote.Children.Add(textContent);
                panelNote.Children.Add(textTime);
                panelNote.Children.Add(buttonDelete);

                if (listNotes.Items.Count % 2 == 0)
                {
                    panelNote.Background = System.Windows.Media.Brushes.AliceBlue;
                }
                else
                {
                    panelNote.Background = System.Windows.Media.Brushes.White;
                }

                listNotes.Items.Add(panelNote);
            }
        }

        public NotePresenter()
        {
            this.Title = "BoxSharp Note";
            this.Content = listNotes;
            this.SizeToContent = SizeToContent.WidthAndHeight;
            this.ShowInTaskbar = false;
            this.Topmost = true;
            NotesManager.Presenter = this;
            this.Closed += new EventHandler(NotePresenter_Closed);

            RefreshNotes();
        }

        void NotePresenter_Closed(object sender, EventArgs e)
        {
            NotesManager.Presenter = null;
        }

        void buttonDelete_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            NoteItem toDelete = button.Tag as NoteItem;
            NotesManager.DeleteNote(toDelete.Note);
        }
    }

    public class NoteItem
    {
        public StackPanel Panel;
        public Note Note;
    }

    public class NotesManager
    {
        public static NotePresenter Presenter = null;

        public static void Refresh()
        {
            notes.Clear();

            DirectoryInfo notesDir = new DirectoryInfo(path);
            FileInfo[] noteFiles = notesDir.GetFiles("*.txt");

            foreach (FileInfo noteFile in noteFiles)
            {
                StreamReader reader = noteFile.OpenText();
                string dateLine = reader.ReadLine();
                if (dateLine == null)
                {
                    reader.Close();
                    continue;
                }

                Note newNote = new Note();
                newNote.HashValue = Path.GetFileNameWithoutExtension(noteFile.Name);

                if (DateTime.TryParse(dateLine, out newNote.Time))
                {
                    string restContent = reader.ReadToEnd();

                    if (restContent != null)
                    {
                        newNote.Content = restContent;
                    }
                }
                else
                {
                    newNote.Content = dateLine + "\r\n";
                    string restContent = reader.ReadToEnd();

                    if (restContent != null)
                    {
                        newNote.Content += restContent;
                    }
                }

                reader.Close();

                notes.Add(newNote);
            }

            if (Presenter != null) Presenter.RefreshNotes();
        }

        public static void AddNote(Note note)
        {
            note.HashValue = note.GetHashValue();
            StreamWriter writer = new StreamWriter(Path.Combine(path, note.HashValue + ".txt"));
            writer.WriteLine(note.Time.ToString());
            writer.WriteLine(note.Content);
            writer.Close();
            Refresh();
        }

        public static void DeleteNote(Note note)
        {
            File.Delete(Path.Combine(path, note.HashValue + ".txt"));
            Refresh();
        }

        public static List<Note> Notes
        {
            get
            {
                return notes;
            }
        }

        public static void SetPath(string thePath)
        {
            path = thePath;
        }

        private static string path = "";
        private static List<Note> notes = new List<Note>();
    }

    public class Note
    {
        public DateTime Time = DateTime.MinValue;
        public string Content = "";
        public string HashValue = "";

        public string GetHashValue()
        {
            return Math.Abs(Time.GetHashCode()).ToString() + Math.Abs(Content.GetHashCode()).ToString();
        }
    }
}
